<?php
final class DB implements ISingleton,IConfig_Get
{
    
      private static $__Instance=Array();

      public static function GetInstance($config=NULL)
      {
            switch (gettype($config))
            {
                  case 'NULL':
                        if(count(self::$__Instance)){
                              return self::$__Instance['Default'];
                        }
                        else{
                              return self::$__Instance['Default']=new EPDO(self::GetConfig());
                        }
                  break;
                  case 'string':
                        if(self::$__Instance[$config['Name']]){
                              return self::$__Instance[$config['Name']];
                        }
                        else{
                              throw new Exception('class.DB.GetInstance：不存在该EPDO实例。');
                        }
                  break;
                  case 'array':
                        if(count(self::$__Instance))
                        {
                              if($config['Name'])
                              {
                                    if(@self::$__Instance[$config['Name']]){
                                         throw new Exception('class.DB.GetInstance：存储名称'.$config['Name'].'己经被占用。');
                                    }
                                    else{
                                          return self::$__Instance[$config['Name']]=new EPDO($config);
                                    }
                              }
                              else{
                                    throw new Exception('class.DB.GetInstance：Default默认存储名称己经被占用，必须指定存储名称。');
                              }
                        }
                        else
                        {
                              if($config['Name']){
                                  return self::$__Instance[$config['Name']]=self::$__Instance['Default']=new EPDO($config);
                              }
                              else{
                                   return self::$__Instance['Default']=new EPDO($config);
                              }
                        }
                  break;
                  default :
                        throw new Exception('class.DB.GetInstance：参数类型错误，只能是string,array,NULL。');
            }
      }

      public static function GetConfig()
	{
            if(class_exists('Config'))
            {
                  if(method_exists('Config','DBServers')){
                        return Config::DBServers('Default');
                  }
                  else{
                        throw new Exception('class.DB.GetConfig：Config配置类中不存在DBServers配置方法。');
                  }
            }
            else{
                  throw new Exception('class.DB.GetConfig：Config配置类不存在。');
            }
	}


      private static function DriverType(&$dbh)
      {
            switch($driverType=$dbh->getAttribute(PDO::ATTR_DRIVER_NAME))
            {
                  case 'mysql':
                        return 'DB_MySQL';
                  break;
                  default:
                        throw new Exception('class.DB.DriverType：DB数据库操作类不支持驱动类型为"'.$driverType.'"的PDO对象。');
            }
      }

      public static function BindRWI($str,$config=NULL)
      {
            $dbh=DB::GetInstance($config);
            return call_user_func_array(array(self::DriverType($dbh),'BindRWI'),array($str));
      }

      public static function CExec($sql,$config=NULL)
      {
            $dbh=self::GetInstance($config);
            return $dbh->Exec($sql);
      }

      public static function PExec($sql,$params,$config=NULL)
      {
            $dbh=self::GetInstance($config);
            $sth=$dbh->Prepare($sql);
            {
                  EPDO::BindSTMT($sth,$params);                  
            }
            return $sth->Execute();
      }

      public static function GetRows($sql,$config=NULL)
      {
            $dbh=self::GetInstance($config);
            return $dbh->Query($sql)->FetchAll();
      }

      public static function PGetRows($sql,$params,$config=NULL)
      {
            $dbh=self::GetInstance($config);
            $sth=$dbh->Prepare($sql);
            {
                  EPDO::BindSTMT($sth,$params);
            }
            $sth->Execute();
            return $sth->FetchAll();
      }

      public static function Insert($tableName,$data,$config=NULL)
      {
            $dbh=self::GetInstance($config);
            $fields=array_keys($data);
            $fieldsStr=join(',',$fields);
            $paramsStr=NULL;
            {
                  foreach ($fields as $key=>$value) {
                        $fields[$key]=':'.$value;
                  }
                  $paramsStr=implode(',',$fields);
            }
            $sql='insert into '.$tableName.'('.$fieldsStr.')values('.$paramsStr.')';
            $sth=$dbh->Prepare($sql);
            {
                  EPDO::BindSTMT($sth,$data);
            }
            return $sth->Execute();
      }

      public static function ErrorCode($config=NULL)
      {
            $dbh=self::GetInstance($config);
            return $dbh->ErrorCode();
      }

      public static function ErrorInfo($config=NULL)
      {
            $dbh=self::GetInstance($config);
            return $dbh->ErrorInfo();
      }

      public static function InsertID($name=NULL,$config=NULL)
      {
            $dbh=self::GetInstance($config);
            return $dbh->LastInsertID($name);
      }

      public static function GetData($sql,$config=NULL)
      {
            $dbh=self::GetInstance($config);
            return call_user_func_array(array(self::DriverType($dbh),'GetData'),array($sql,&$dbh));
      }

      public static function PGetData($sql,$params,$config=NULL)
      {
            $dbh=self::GetInstance($config);            
            return call_user_func_array(array(self::DriverType($dbh),'PGetData'),array($sql,$params,&$dbh));
      }

      public static function GetRowByID($tableName,$primary,$config=NULL)
      {
            $dbh=self::GetInstance($config);
            return call_user_func_array(array(self::DriverType($dbh),'GetRowByID'),array($tableName,$primary,&$dbh));
      }

      public static function GetRowByValue($tableName,$fieldName,$value,$config=NULL)
      {
            $dbh=self::GetInstance($config);
            return call_user_func_array(array(self::DriverType($dbh),'GetRowByValue'),array($tableName,$fieldName,$value,&$dbh));
      }

      /**
       * Start UnStandard
       */
	  public static function GetRowByIDForFields($tableName,$primary,$field,$config=NULL)
      {
            $dbh=self::GetInstance($config);
            return call_user_func_array(array(self::DriverType($dbh),'GetRowByIDForFields'),array($tableName,$primary,$field,&$dbh));
      }
      /**
       * End UnStandard
       */

      public static function GetValueByID($tableName,$primary,$field,$config=NULL)
      {
            $dbh=self::GetInstance($config);
            return call_user_func_array(array(self::DriverType($dbh),'GetValueByID'),array($tableName,$primary,$field,&$dbh));
      }

      public static function DeleteRowByID($tableName,$primary,$config=NULL)
      {
            $dbh=self::GetInstance($config);
            return call_user_func_array(array(self::DriverType($dbh),'DeleteRowByID'),array($tableName,$primary,&$dbh));
      }

      public static function UpdateRowByID($tableName,$primary,$data,$config=NULL)
      {
            $dbh=self::GetInstance($config);           
            return call_user_func_array(array(self::DriverType($dbh),'UpdateRowByID'),array($tableName,$primary,$data,&$dbh));
      }

      public static function UpdateRowByField($tableName,$fieldNameAndValue,$data,$config=NULL)
      {
            $dbh=self::GetInstance($config);
            return call_user_func_array(array(self::DriverType($dbh),'UpdateRowByField'),array($tableName,$fieldNameAndValue,$data,&$dbh));
      }

      public static function BeginTransaction($config=NULL)
      {
            $dbh=self::GetInstance($config);
            return $dbh->BeginTransaction();
      }
      
      public static function Commit($config=NULL)
      {
            $dbh=self::GetInstance($config);
            return $dbh->Commit();
      }

      public static function RollBack($config=NULL)
      {
            $dbh=self::GetInstance($config);
            return $dbh->RollBack();
      }

      public static function InTransaction($config=NULL)
      {
            $dbh=self::GetInstance($config=NULL);
            return $dbh->InTransaction();
      }

    public static function Release($name=NULL)
    {
        if($name)
        {
            if(@self::$__Instance[$name])
            {
                self::$__Instance[$name]=NULL;
                unset(self::$__Instance[$name]);                
            }
            else
            {
                throw new Exception('不存在名称为'.$name.'的链接。');
            }
        }
        else
        {
            foreach(self::$__Instance as &$connect)
            {
                $connect=NULL;
                unset($connect);
            }
        }
    }
}
?>